#include "client.h"
#include "authorization.h"
#include "createchat.h"



class Overlay : public QWidget
{
public:
    Overlay(QWidget* parent = nullptr) : QWidget(parent) {}

protected:
    void mousePressEvent(QMouseEvent* event) override
    {
        Q_UNUSED(event);
        if (parentWidget())
        {
            auto client = qobject_cast<Client*>(parentWidget());
            if (client)
            {
                client->hideOverlay();
            }
        }
    }
};


Client::Client(QWidget *parent)
    : QMainWindow(parent), animationRunning(false)
{
    this->resize(1000, 800);

    build();
    connecting();
    renderingChats();

    notifier = new QSocketNotifier(clientSock, QSocketNotifier::Read, this);
    connect(notifier, &QSocketNotifier::activated, this, &Client::processServerMessages);
}

Client::~Client() {}

void Client::build()
{
    upperChatsHLayout = new QHBoxLayout;
    searchChat = new QLineEdit("Поиск");        // the upper part of the left part
    settingMenuButton = new QPushButton;
    settingMenuButton->setIcon(QIcon(":/Image/Images/settingsMenu.png"));
    settingMenuButton->setStyleSheet("QPushButton { border: none; }");
    settingMenuButton->setFixedSize(30, 40);
    settingMenuButton->setIconSize(QSize(30, 40));
    searchChat->setFixedHeight(40);
    upperChatsHLayout->addWidget(settingMenuButton);
    upperChatsHLayout->addWidget(searchChat);



    createChatHLayout = new QHBoxLayout;
    createChatButton = new QPushButton(tr("Create a chat")); // creating a chat
    createChatHLayout->addWidget(createChatButton);



    chatsVLayout = new QVBoxLayout;
    chatsList = new QListWidget;
    chatsVLayout->addLayout(upperChatsHLayout);    // chat selection and merge
    chatsVLayout->addLayout(createChatHLayout);
    chatsVLayout->addWidget(chatsList);
    chatsVLayout->setContentsMargins(0, 0, 0, 0);
    chatsVLayout->setSpacing(0);



    upperChatMsgHLayout = new QHBoxLayout;
    upperLabel = new QLabel;              // the upper part of the right part
    upperLabel->setFixedHeight(40);
    upperChatMsgHLayout->addWidget(upperLabel);



    msgVLayout = new QVBoxLayout;
    msgList = new QListWidget;          // displaying the chat content
    msgVLayout->addLayout(upperChatMsgHLayout);
    msgVLayout->addWidget(msgList);



    lowerChatHLayout = new QHBoxLayout;
    msgEdit = new QLineEdit("Написать сообщение...");
    msgEdit->setFixedHeight(30);
    msgEdit->setStyleSheet("QLineEdit { border: none; }");

    msgSendButton = new QPushButton;                    // the lower part of the right part
    msgSendButton->setFixedSize(30, 30);
    msgSendButton->setIcon(QIcon(":/Image/Images/send.png"));
    msgSendButton->setIconSize(QSize(30, 30));
    msgSendButton->setStyleSheet("QPushButton { border: none }");

    lowerChatHLayout->addWidget(msgEdit, 1);
    lowerChatHLayout->addWidget(msgSendButton, 0, Qt::AlignRight);

    msgVLayout->addLayout(lowerChatHLayout);
    msgVLayout->setContentsMargins(0, 0, 0, 0);
    msgVLayout->setSpacing(0);



    stackMain = new QStackedWidget;
    stackRightPartLabel = new QLabel(tr("Not a single chat is selected")); // the right part of the stack
    stackMain->addWidget(stackRightPartLabel);
    stackMain->setLayout(msgVLayout);



    leftWidget = new QWidget;
    leftWidget->setLayout(chatsVLayout);
    leftWidget->setMinimumWidth(200);                     // merging the left and right parts
    splitterBetweenListDisplay = new QSplitter(Qt::Horizontal);
    splitterBetweenListDisplay->addWidget(leftWidget);
    splitterBetweenListDisplay->addWidget(stackMain);
    splitterBetweenListDisplay->setCollapsible(0, false);
    splitterBetweenListDisplay->setCollapsible(1, false);
    splitterBetweenListDisplay->setHandleWidth(0);
    setCentralWidget(splitterBetweenListDisplay);


    settingMenu = new settingsMenu(this);
    settingMenu->setFixedWidth(250);
    settingMenu->setStyleSheet("background-color: #1c1c1c; color: white;");

    animation = new QPropertyAnimation(settingMenu, "geometry");
    animation->setDuration(200);
    animation->setStartValue(QRect(-settingMenu->width(), 0, settingMenu->width(), height()));
    animation->setEndValue(QRect(0, 0, settingMenu->width(), height()));
    settingMenu->hide();

    overlay = new QWidget(this);
    overlay->setStyleSheet("background:transparent;");
    overlay->hide();
}

void Client::connecting()
{
    connect(createChatButton, &QPushButton::clicked, this, [this]()
    {
        createChat* chat = new createChat;
        chat->setModal(true);
        connect(chat, &QDialog::accepted, this, &Client::updateChatList);
        chat->show();
    });
    connect(settingMenuButton, &QPushButton::clicked, [this]()
    {
        if(!animationRunning)
        {
            if(settingMenu->isHidden())
            {
                settingMenu->show();
                showOverlay();
                animation->setDirection(QPropertyAnimation::Forward);
                animation->start();
                animationRunning = true;
            }

        }
    });
    connect(animation, &QPropertyAnimation::finished, [this]()
    {
        animationRunning = false;
        if(settingMenu->geometry().x() < 0)
        {
            settingMenu->hide();
        }
    });
    connect(this, &Client::updateChatListSignal, this, &Client::updateChatList);
}

void Client::resizeEvent(QResizeEvent *event)
{
    QMainWindow::resizeEvent(event);
    if (settingMenu->isVisible())
    {
        settingMenu->setGeometry(0, 0, settingMenu->width(), height());
    }
    overlay->resize(size());
}

void Client::mousePressEvent(QMouseEvent *event)
{
    if (settingMenu->isVisible() && !settingMenu->geometry().contains(event->pos()))
    {
        hideOverlay();
    }
    QMainWindow::mousePressEvent(event);
}

void Client::showOverlay()
{
    overlay->setGeometry(0, 0, width(), height());
    overlay->show();
}

void Client::renderingChats()
{
    chatsList->clear();
    char buffer[BUFFER_SIZE];
    int count = 0;
    QString sqlQuery = QString("SELECT COUNT(*) FROM listChat WHERE nickName = '%1'").arg(clientStartNickname());
    std::string sqlQueryStd = sqlQuery.toStdString();

    send(clientSock, sqlQueryStd.c_str(), sqlQueryStd.length(), 0);
    recv(clientSock, buffer, sizeof(buffer), 0);
    count = atoi(buffer);

    if(count > 0)
    {
        sqlQuery = QString("SELECT chat FROM listChat WHERE nickName = '%1'").arg(clientStartNickname());
        sqlQueryStd = sqlQuery.toStdString();

        send(clientSock, sqlQueryStd.c_str(), sqlQueryStd.length(), 0);
        recv(clientSock, buffer, sizeof(buffer), 0);

        QString response = buffer;
        QStringList chatListStr = response.split("\n", Qt::SkipEmptyParts);
        for(int i = 0; i < count; ++i)
        {
            chatsList->addItem(chatListStr[i]);
        }
    }
}

void Client::hideOverlay()
{
    animation->setDirection(QPropertyAnimation::Backward);
    animation->start();
    overlay->hide();
}

void Client::updateChatList()
{
    chatsList->clear();
    renderingChats();
}

void Client::processServerMessages()
{
    char buffer[BUFFER_SIZE];
    int bytes_read = recv(clientSock, buffer, sizeof(buffer), 0);
    if(bytes_read > 0)
    {
        QString message = buffer;
        if(message == "update")
        {
            emit updateChatListSignal();
        }
    }
    notifier->setEnabled(true);
}
